home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
United Public Domain Gold 4
/
United Public Domain Gold 4.iso
/
scope
/
sc004.dms
/
sc004.adf
/
MacFont
/
unpack.c
< prev
Wrap
C/C++ Source or Header
|
1988-04-26
|
5KB
|
201 lines
/*
* Macintosh font suitcase unpacker by John O'Neill
*
* Amiga modifications by Rico Mariani
*
* The -x flag is used to skip the 128 info section that is placed
* at the head of the file when the suitcase is uploaded from
* the Mac by some versions of xmodem.
*
* (C)1987 John O'Neill & Rico Mariani
*
*/
#include <exec/types.h>
#include "extract.h"
#include <stdio.h>
void *malloc();
void *PtoC();
int debug = 1;
main(argc,argv)
int argc;
char **argv;
{
unsigned char *res, rheader[16];
int i, j, c;
int Data_loc, Map_loc, Data_length, Map_length, Res_length;
int Type_List_loc, Name_List_loc;
int Num_Res_Types, Type_loc, Num_Fonts, Ref_List_loc;
int Ref_loc, Res_ID, temp, Res_Name_loc, Res_Attributes;
int Res_Data_loc;
int Font_ID, Point_Size, Font_Num, Font_Size;
unsigned char **Font_Name;
unsigned char File_Name[32];
FILE *f,*fontfile;
int skip = 0;
/* Start up */
if (argc < 2 || argc > 4) {
fprintf(stderr,"Usage: %s [-x] FontFile\n",argv[0]);
exit(1);
}
if (!strcmp(argv[1],"-x"))
skip = 1;
f = fopen(argv[1+skip],"r");
if (!f) {
fprintf(stderr,"%s: Cannot open %s\n",argv[0],argv[1+skip]);
exit(1);
}
/* Skip .info file sent by XMODEM */
if (skip) for(i = 0; i < 128; i++) fgetc(f);
/* Get resource file header */
fread( rheader, sizeof(rheader), 1, f);
Data_loc = X_LONG(rheader + 0);
Map_loc = X_LONG(rheader + 4);
Data_length = X_LONG(rheader + 8);
Map_length = X_LONG(rheader + 12);
Res_length = Data_length + Map_length + 256;
/* allocate memory for the rest of the resource */
res = malloc(Res_length);
/* read in everything but the header */
fread( res+16, Res_length-16, 1, f );
fclose(f);
/* Look for FONT resources in the resource map */
Type_List_loc = Map_loc + X_UWORD(res + Map_loc + 24);
Name_List_loc = Map_loc + X_UWORD(res + Map_loc + 26);
Num_Res_Types = 1 + X_UWORD(res + Type_List_loc);
printf("There are %d Res Types in the file\n", Num_Res_Types);
for(i = 0; i < Num_Res_Types; i++) {
Type_loc = Type_List_loc + i*10 + 2;
if (X_ULONG(res + Type_loc) == 'FONT') {
Num_Fonts = 1 + X_UWORD(res+Type_loc+4);
Ref_List_loc = Type_List_loc +
X_UWORD(res + Type_loc + 6);
printf("Found FONT rsrc with %d fonts\n", Num_Fonts);
}
}
/* Get the FONT names first: this is the name of the Resources
which have ResId a multiple of 128 */
Font_Num = 1;
/* need one pointer for each possible font id */
Font_Name = malloc(sizeof(char *) * 256);
if (!Font_Name) {
printf("Error, no memory for font name pointer array\n");
exit(-1);
}
for(i = 0; i < Num_Fonts; i++) {
Ref_loc = Ref_List_loc + 12*i;
Res_ID = X_UWORD(res + Ref_loc);
Font_ID = Res_ID >> 7;
Point_Size = Res_ID & 0x7f;
if (Point_Size == 0) {
temp = X_UWORD(res + Ref_loc + 2);
if (temp == 0xffff) {
Font_Name[Font_ID] = malloc(10);
if (!Font_Name[Font_ID]) {
printf("Error, no memory for name\n");
exit(-1);
}
sprintf(Font_Name[Font_ID],"FONT%d",
Font_Num );
Font_Num++;
}
else {
Res_Name_loc = Name_List_loc + temp;
Font_Name[Font_ID] = PtoC(res+Res_Name_loc);
}
}
}
/* Get the info on each of the FONT resources found */
for(i = 0; i < Num_Fonts; i++) {
Ref_loc = Ref_List_loc + 12*i;
Res_ID = X_UWORD(res + Ref_loc );
Font_ID = Res_ID >> 7;
Point_Size = Res_ID & 0x7f;
temp = X_UWORD(res + Ref_loc + 2);
Res_Name_loc = (temp == 0xffff) ? -1 : Name_List_loc+temp;
Res_Attributes = res[Ref_loc + 4];
Res_Data_loc = Data_loc + X_UTRIP(res + Ref_loc + 5);
Font_Size = X_ULONG( res + Res_Data_loc );
if (Point_Size != 0) {
for(j = 0;; j++) {
c = Font_Name[Font_ID][j];
if (c == ' ') c = '_';
if (c != 0)
File_Name[j] = c;
else
break;
}
File_Name[j] = '.';
j++;
sprintf(&File_Name[j],"%d",Point_Size);
printf("Font:%s %d -> File:%s (Size = %d)\n",
Font_Name[Font_ID],Point_Size,File_Name,
Font_Size);
fontfile = fopen(File_Name,"w");
if (!fontfile) {
fprintf(stderr,"%s: Cannot open %s\n",
argv[0],File_Name);
exit(1);
}
fwrite( res+Res_Data_loc+4, Font_Size, 1, fontfile);
fclose(fontfile);
}
}
}
void *PtoC(s1)
register unsigned char *s1;
{
register unsigned char *s2;
register int i;
int len;
unsigned char *s;
len = *s1++;
s = s2 = malloc(len + 1);
if (!s2) {
printf("Error, not enough memory to make C string\n");
exit(-1);
}
for (i= len; --i>=0; ) *s2++ = *s1++;
*s2 = 0;
return(s);
}